package aspect;

/**
 * @author azzhu
 * @create 2020-08-15 10:35:53
 */
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;

@Aspect  //表明该类是一个切面类
@Component//加入到IOC容器中，采用注解方式
@Order
public class UserAspect{
  //  @Before("execution(* aspect.UserDao.*(..))")
    public void before(JoinPoint joinPoint){
        //1.获取目标方法的方法名
        //获取目标方法的签名:除了方法体之后，都是签名部分
        Signature signature = joinPoint.getSignature();

        String methodName = signature.getName();

        //2.获取目标方法执行时传入的参数列表
        Object[] args = joinPoint.getArgs();
        List<Object> argList = Arrays.asList(args);
        System.out.println("[AOP前置通知]["+methodName+"方法开始了][参数有："+argList+"]");
    }

  //  @AfterReturning(value="execution(* aspect.UserDao.update(..))",returning="returnVal")
    public void afterReturin(JoinPoint joinPoint,Object returnVal){
        String methodName = joinPoint.getSignature().getName();
        System.out.println("[AOP返回通知]["+methodName+"方法结束了][结果是："+returnVal+"]");
    }

    //环绕通知
    @Around(value="UserAspect.myPointcut()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
        Object result = null;

        String methodName = proceedingJoinPoint.getSignature().getName();
        try {
            //1.显示方法开始
            Object[] args = proceedingJoinPoint.getArgs();
            List<Object> argList = Arrays. asList(args);
            System. out.println("[AOP环绕通知][" +methodName +"方法开始了][参数有：" +argList +"]" );
            //★在环绕通知中一定要调用joinPoint.proceed()来执行目标方法，否则目标方法将不会被执行
            //★一定要将目标方法的返回值返回，如果不返回，则目标方法的调用者就拿不到返回结果了
            result = proceedingJoinPoint.proceed();
            System. out.println("[AOP环绕通知][" +methodName +"方法结束了][结果是：" +result +"]" );
        } catch (Exception e) {
            //e.printStackTrace();
            //3.方法抛出了异常
            System. out.println("[AOP环绕通知][" +methodName +"方法抛异常了][异常对象：" +e +"]" );
        } finally {
            //4.方法最终结束
            System. out.println("[AOP后置通知][" +methodName +"方法最终结束了]" );
        }
        return result;
    }

   // @AfterThrowing(value="UserAspect.myPointcut()",throwing="e")
    public void afterThrowing(JoinPoint joinPoint,Throwable e){
        String methodName = joinPoint.getSignature().getName();
        System.out.println("[AOP异常通知]["+methodName+"方法抛异常了][异常对象："+e+"]");
    }

   // @After("myPointcut()")
    public void after(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        System.out.println("[AOP后置通知]["+methodName+"方法最终结束了]");
    }

    //统一声明切入点表达式，以便于重用
    @Pointcut("execution(* aspect.UserDao.add(..))")
    private void myPointcut(){}

}
